package me.xplabs.model.combatunit 

{
	import flash.utils.Dictionary;
	import flash.utils.getTimer;
	import me.xplabs.AppFacade;
	import me.xplabs.Globals;
	import me.xplabs.gemo.Point2D;
	import me.xplabs.interfaces.IHeartbeat;
	import me.xplabs.magic.LongDistanceMagic;
	import me.xplabs.model.msg.MsgAddBuffActor;
	import me.xplabs.model.msg.MsgAddEffect;
	import me.xplabs.model.RolePositionManager;
	import me.xplabs.model.msg.MsgHitActor;
	import me.xplabs.model.msg.MsgUseSkill;
	import me.xplabs.model.skill.BaseSkill;
	import me.xplabs.model.skill.MSkillInfo;
	import me.xplabs.model.skill.Skill;
	import me.xplabs.model.skill.SkillManager;
	import me.xplabs.msg.NotificationFight;
	import me.xplabs.msg.NotificationName;
	import me.xplabs.utils.MacroObjPool;
	import me.xplabs.utils.Utils;
	/**
	 * 建筑基本信息
	 * ...
	 * @author xiaohan
	 */
	public class MBuildInfo extends BaseBuild implements IHeartbeat
	{
		/** 唯一Id*/
		public var soleId:int;
		/** 格子坐标X轴*/
		public var cellX:int;
		/** 格子坐标Y轴*/
		public var cellY:int;
		/** 建筑的像素坐标X轴*/
		public var curPosX:Number;
		/** 建筑的像素坐标Y轴*/
		public var curPosY:Number;
		/** 建筑的旗帜信息*/
		public var flagInfo:BaseFlag;
		/** 技能管理器*/
		public var skillManager:SkillManager;
		/** 格子坐标上面的角色引用*/
		//public var paths:Dictionary;
		/** 攻击遍历范围内的角色引用*/
		private var _roles:Vector.<MRoleInfo>;
		/** 走出遍历攻击范围的角色引用*/
		private var _changeRoles:Vector.<MRoleInfo>;
		private var _now:uint;
		private var _total:uint;
		private var _skills:Vector.<MSkillInfo>;
		
		/* 在攻击范围内的角色*/
		private var _areaRoles:Vector.<MRoleInfo>;
		private var _timeKey:int = -1;
		private var _hasSkills:Vector.<BaseSkill>;
		public function MBuildInfo(p_resId:int = 0, p_cellX:int = 0, p_cellY:int = 0) 
		{
			resId = p_resId;
			this.cellX = p_cellX;
			this.cellY = p_cellY;
			curPosX = cellX * Globals.cellW;
			curPosY = cellY * Globals.cellH;
			skillManager = new SkillManager();
			_roles = new Vector.<MRoleInfo>();
			_changeRoles = new Vector.<MRoleInfo>();
			_areaRoles = new Vector.<MRoleInfo>();
			_skills = new Vector.<MSkillInfo>();
			skillManager.useSkillCall = useSkillHandler;
		}
		
		private function useSkillHandler(p_skill:Skill):Boolean
		{
			updateRole();
			var len:int = _roles.length;
			if (len <= 0) return false;
			_areaRoles.length = 0;
			for (var i:int = 0; i < len; i++) 
			{
				var curRole:MRoleInfo = _roles[i];
				//var dx:Number = curRole.curPosX - curPosX;
				//var dy:Number = curRole.curPosY - curPosY;
				//if (Math.sqrt(dx * dx + dy * dy) <= areaW)
				//{
					//_areaRoles.push(_roles[i]);
				//}
				var ax:int = curRole.curPosX - curPosX;
				var ay:int = curRole.curPosY - curPosY;
				if (Math.abs(ax) > areaW || Math.abs(ay) > areaH) continue;
				if (Utils.checkPointInEllipse(ax, ay, areaW, areaH))
				{
					_areaRoles.push(_roles[i]);
				}
			}
			len = _areaRoles.length;
			if (len <= 0) return false;
			curRole = _areaRoles[0];
			for (i = 1; i < len; i++) 
			{
				if (_areaRoles[i].curLife < curRole.curLife)
				{
					curRole = _areaRoles[i];
				}
			}
			//curRole.life = Math.max(0, curRole.life-p_skill.hit);
			//trace(curRole.soleId + "敌人血量=" + curRole.life);
			//sendMsg(NotificationName.FIGHT_MAP_MANAGER, new MsgHitActor(curRole.soleId, p_skill.hit), NotificationFight.HIT_ACTOR);
			
			/*var tempSkill:MSkillInfo = MacroObjPool.getObj(MSkillInfo, 1, 1);
			//var tempSkill:MSkillInfo = new MSkillInfo();
			tempSkill.curRoleInfo = curRole;
			tempSkill.title = p_skill.title;
			tempSkill.baseId = p_skill.baseId;
			tempSkill.skillId = p_skill.skillId;
			tempSkill.resId = p_skill.resId;
			tempSkill.area = p_skill.area;
			tempSkill.describe = p_skill.describe;
			//tempSkill.cdGap = p_skill.cdGap;
			tempSkill.cdGap = cdGap;
			tempSkill.hitId = p_skill.hitId;
			tempSkill.injuredId = p_skill.injuredId;
			tempSkill.isAOE = p_skill.isAOE;
			tempSkill.isPath = p_skill.isPath;
			tempSkill.skillTypes = p_skill.skillTypes.slice();
			//tempSkill.hit = p_skill.hit;
			tempSkill.hit = attack;
			//tempSkill.speed = attackSpeed;
			tempSkill.magic = p_skill.magic;
			tempSkill.speed = p_skill.speed;
			tempSkill.startX = curPosX;
			tempSkill.startY = curPosY;
			tempSkill.endX = curRole.curPosX;
			tempSkill.endY = curRole.curPosY;
			tempSkill.curPosX = curPosX;
			tempSkill.curPosY = curPosY;
			tempSkill.soleId = Globals.soleId;
			tempSkill.attackRoleId = curRole.soleId;
			//tempSkill.heartbeat();
			_skills.push(tempSkill);*/
			
			
			var tempSkill:LongDistanceMagic = MacroObjPool.getObj(LongDistanceMagic, 1, 1);
			//var tempSkill:LongDistanceMagic = new LongDistanceMagic();
			tempSkill.title = p_skill.title;
			tempSkill.baseId = p_skill.baseId;
			tempSkill.skillId = p_skill.skillId;
			tempSkill.resId = p_skill.resId;
			tempSkill.describe = p_skill.describe;
			tempSkill.hitId = p_skill.hitId;
			tempSkill.injuredId = p_skill.injuredId;
			tempSkill.isAOE = p_skill.isAOE;
			tempSkill.isPath = p_skill.isPath;
			tempSkill.skillTypes = p_skill.skillTypes.slice();
			tempSkill.hit = attack;
			tempSkill.magic = p_skill.magic;
			tempSkill.gravity = p_skill.gravity;
			tempSkill.soleId = Globals.soleId;
			tempSkill.aoeAreaW = p_skill.aoeAreaW;
			tempSkill.aoeAreaH = p_skill.aoeAreaH;
			tempSkill.aoeAreaCellW = p_skill.aoeAreaCellW;
			tempSkill.aoeAreaCellH = p_skill.aoeAreaCellH;
			tempSkill.attackRoleId = curRole.soleId;
			var targetPoint2d:Point2D = MacroObjPool.getObj(Point2D, 1, 1);
			targetPoint2d.setXY(curRole.curPosX, curRole.curPosY);
			var sourcePoint2d:Point2D = MacroObjPool.getObj(Point2D, 1, 1);
			sourcePoint2d.setXY(curPosX, curPosY);
			tempSkill.initMagic(targetPoint2d, sourcePoint2d, p_skill.speed, p_skill.gravity, p_skill.magicType);
			_skills.push(tempSkill);
			
			sendMsg(NotificationName.FIGHT_NOTIFICATION, tempSkill, NotificationFight.USE_SKILL);
			return true;
		}
		
		private function sortRole(p1:MRoleInfo, p2:MRoleInfo):Number
		{
			return p1.curLife- p2.curLife;
		}
		public function heartbeat():void 
		{
			var prev:uint = getTimer() - _now;
			_now = getTimer();
			_total += prev;
			var gap:uint = _total / 300;
			if (gap >= 1)
			{
				_total -= gap * 300;
				updateRole();
			}
			//updateRole();
			skillManager.heartbeat(0);
			var len:int = _skills.length;
			for (var i:int = len - 1; i >= 0; i--)
			{
				if (_skills[i].heartbeat(prev))
				{
					removeSkill(_skills.splice(i, 1)[0]);
				}
			}
		}
		
		private function removeSkill(p_mSkillInfo:MSkillInfo):void
		{
			Globals.delSoleId(p_mSkillInfo.soleId);
			sendMsg(NotificationName.FIGHT_NOTIFICATION, p_mSkillInfo.soleId, NotificationFight.REMOVE_HIT_EFFECT);
			var tempHit:int = p_mSkillInfo.hit;
			var tempId:int = p_mSkillInfo.attackRoleId
			var tempInjured:String = p_mSkillInfo.injuredId;
			if (tempInjured != null && tempInjured != "")
			{
				sendMsg(NotificationName.FIGHT_NOTIFICATION, new MsgAddEffect(tempInjured, p_mSkillInfo.endX, p_mSkillInfo.endY), NotificationFight.ADD_EFFECT);
			}
			if (p_mSkillInfo.isAOE)
			{
				//trace(p_mSkillInfo.endX, p_mSkillInfo.endY, p_mSkillInfo.aoeAreaCellW, p_mSkillInfo.aoeAreaCellH);
				var tempRoles:Vector.<MRoleInfo> = injuredRole(p_mSkillInfo.endX, p_mSkillInfo.endY, p_mSkillInfo.aoeAreaCellW, p_mSkillInfo.aoeAreaCellH);
				var len:int = tempRoles.length;
				//print("范围攻击的敌人个数=" + len);
				for (var i:int = 0; i < len; i++) 
				{
					var ax:int = tempRoles[i].curPosX - p_mSkillInfo.endX;
					var ay:int = tempRoles[i].curPosY - p_mSkillInfo.endY;
					if (Utils.checkPointInEllipse(ax, ay, p_mSkillInfo.aoeAreaW, p_mSkillInfo.aoeAreaH))
					{
						sendMsg(NotificationName.FIGHT_MAP_MANAGER, new MsgHitActor(tempRoles[i].soleId, tempHit), NotificationFight.HIT_ACTOR);
					}
				}
			}else
			{
				sendMsg(NotificationName.FIGHT_MAP_MANAGER, new MsgHitActor(tempId, tempHit), NotificationFight.HIT_ACTOR);
			}
			p_mSkillInfo.dispose();
			MacroObjPool.dispose(p_mSkillInfo);
			p_mSkillInfo = null;
			//curRole.life = Math.max(0, curRole.life-p_mSkillInfo.hit);
		}
		
		
		private function injuredRole(px:int, py:int, hitAreaCellW:int, hitAreaCellH:int):Vector.<MRoleInfo>
		{
			var paths:Dictionary = RolePositionManager.i.paths;
			var tempCellX:int = int(px / Globals.cellW);
			var tempCellY:int = int(py / Globals.cellH);
			var tempRoles:Vector.<MRoleInfo> = new Vector.<MRoleInfo>();
			//var ax:int = curRole.curPosX - curPosX;
			//var ay:int = curRole.curPosY - curPosY;
			if (paths)
			{
				var startX:int = tempCellX - hitAreaCellW;
				var startY:int = tempCellY - hitAreaCellH;
				var endX:int = tempCellX + hitAreaCellW;
				var endY:int = tempCellY + hitAreaCellH;
				for (var i:int = startX; i <= endX; i++)
				{
					for (var j:int = startY; j <= endY; j++)
					{
						var temp:Vector.<MRoleInfo> = paths[i + "-" + j];
						if (temp && temp.length > 0)
						{
							var len:int = temp.length;
							for (var k:int = 0; k < len; k++) 
							{
								tempRoles.push(temp[k]);
								//trace("被添加进的角色id" + temp[k].soleId);
							}
						}
					}
				}
			}
			return tempRoles;
		}
		
		/**
		 * 更新范围内的所有敌人引用
		 */
		private function updateRole():void
		{
			var prevRoles:Vector.<MRoleInfo> = _roles.slice();
			_changeRoles.length = 0;
			
			
			_roles.length = 0;
			var paths:Dictionary = RolePositionManager.i.paths;
			if (paths)
			{
				var startX:int = cellX - areaCellW;
				var startY:int = cellY - areaCellH;
				var endX:int = cellX + areaCellW;
				var endY:int = cellY + areaCellH;
				for (var i:int = startX; i <= endX; i++)
				{
					for (var j:int = startY; j <= endY; j++)
					{
						var temp:Vector.<MRoleInfo> = paths[i + "-" + j];
						if (temp && temp.length > 0)
						{
							var len:int = temp.length;
							for (var k:int = 0; k < len; k++) 
							{
								_roles.push(temp[k]);
								//trace("被添加进的角色id" + temp[k].soleId);
							}
						}
					}
				}
			}
			//_roles.sort(sortRole);
			findDifferent(prevRoles, _roles);
		}
		/**
		 * 查找走出攻击范围的角色
		 * @param	prevRoles
		 * @param	roles
		 */
		private function findDifferent(prevRoles:Vector.<MRoleInfo>, roles:Vector.<MRoleInfo>):void
		{
			var obj:Object = { };
			var len:int = roles.length;
			for (var i:int = 0; i < len; i++) 
			{
				obj[roles[i].soleId] = true;
			}
			len = prevRoles.length;
			for (i = 0; i < len; i++) 
			{
				if (!obj[prevRoles[i]])
				{
					_changeRoles.push(prevRoles[i]);
				}
			}
		}
		/**
		 * 初始化技能列表
		 * @param	p_skills
		 */
		public function initSkillList(p_skills:Vector.<BaseSkill>):void 
		{
			skillManager.clearSkills();
			if (_timeKey != -1)
			{
				Globals.timeManager.removeGap(_timeKey);
				_timeKey = -1;
			}
			if (!p_skills) return;
			_hasSkills = p_skills;
			_timeKey = Globals.timeManager.addDelay(1,delayInitSkills);
		}
		
		private function delayInitSkills():void 
		{
			_timeKey = -1;
			var len:int = _hasSkills.length;
			for (var i:int = 0; i < len; i++) 
			{
				var p_skill:BaseSkill = _hasSkills[i];
				var tempSkill:Skill = MacroObjPool.getObj(Skill, 1, 1);
				tempSkill.title = p_skill.title;
				tempSkill.baseId = p_skill.baseId;
				tempSkill.skillId = p_skill.skillId;
				tempSkill.resId = p_skill.resId;
				tempSkill.area = areaW;
				tempSkill.describe = p_skill.describe;
				tempSkill.cdGap = cdGap;
				tempSkill.hitId = p_skill.hitId;
				tempSkill.injuredId = p_skill.injuredId;
				tempSkill.isAOE = p_skill.isAOE;
				tempSkill.isPath = p_skill.isPath;
				tempSkill.skillTypes = p_skill.skillTypes.slice();
				tempSkill.gravity = p_skill.gravity;
				tempSkill.hit = attack;
				tempSkill.speed = p_skill.speed;
				tempSkill.magic = p_skill.magic;
				tempSkill.magicType = p_skill.magicType;
				tempSkill.aoeAreaW = p_skill.aoeAreaW;
				tempSkill.aoeAreaH = p_skill.aoeAreaH;
				tempSkill.aoeAreaCellW = p_skill.aoeAreaCellW;
				tempSkill.aoeAreaCellH = p_skill.aoeAreaCellH;
				tempSkill.gravity = p_skill.gravity;
				//trace(tempSkill.aoeAreaW, tempSkill.aoeAreaH, tempSkill.aoeAreaCellW, tempSkill.aoeAreaCellH);
				skillManager.addSkill(tempSkill);
			}
		}
		public function dispose():void
		{
			//移除特效
			var len:int = _skills.length;
			for (var i:int = len-1; i >= 0; i--) 
			{
				removeSkill(_skills.splice(i, 1)[0]);
			}
		}
	}
}